/**
 * Copyright 2018 人人开源 http://www.renren.io
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

package com.freeter.interceptor;


import com.freeter.annotation.RoleCheckAnnotation;
import com.freeter.common.exception.RRException;
import com.freeter.common.utils.RedisUtils;
import com.freeter.modules.sys.service.SysUserRoleService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Field;

/**
 * 验证用户是否具备角色
 */
@Component
public class AuthInterceptor extends HandlerInterceptorAdapter {
    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    private SysUserRoleService userRoleService;

    public static final String USER_KEY = "userId";

    @Override
    public boolean preHandle(HttpServletRequest request,
                             HttpServletResponse response,
                             Object handler) throws Exception {
        RoleCheckAnnotation annotation;
        if(handler instanceof HandlerMethod) {
            annotation = ((HandlerMethod) handler).getMethodAnnotation(RoleCheckAnnotation.class);
         }else{
            return true;
        }

        if(annotation == null){
            return true;
        }

        //设置userId到request里，后续根据userId，获取用户信息
        Long userId = (Long)request.getAttribute(USER_KEY);
        if(null == userId){
            throw new RRException("没有权限");
        }

        String roles = redisUtils.get("login_user_roles_" + userId);
        if(StringUtils.isBlank(roles)) {
            roles = userRoleService.queryRoleNameString(userId);
        }

        String annoRoles1 = annotation.roles();
        String[] userRoleNames = roles.split(",");
        String[] annoRoleNames = annoRoles1.split(",");
        for(String role : userRoleNames){
            for(String annoRole : annoRoleNames){
                if(role.equals(annoRole)){
                    return true;
                }
            }
        }
        throw new RRException("没有权限");
    }

    public static <T> Object getFieldValue(T object, String property) {
        if (object != null && property != null) {
            Class<T> currClass = (Class<T>) object.getClass();

            try {
                Field field = currClass.getDeclaredField(property);
                field.setAccessible(true);
                return field.get(object);
            } catch (NoSuchFieldException e) {
                throw new IllegalArgumentException(currClass + " has no property: " + property);
            } catch (IllegalArgumentException e) {
                throw e;
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return null;
    }
}